home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGBLER / WASM211B.LZH / SHOW87.ASM < prev    next >
Assembly Source File  |  1988-04-25  |  33KB  |  1,255 lines

  1.  
  2.  Title 'Wolfware Assembler Sample Program', '8087 State Display'
  3.  
  4. ;=============================================================================
  5. ; Show87
  6. ; Copyright (c) 1987-1988 Eric Tauck
  7. ; All Rights Reserved
  8. ;
  9. ; This a memory resident program to display the present state of an
  10. ; installed 8087 coprocessor.  Once assembled, to execute, type:
  11. ;
  12. ;   SHOW87 [/R]
  13. ;
  14. ; If run without any options, the program executes a DOS shell and can be
  15. ; removed from memory by typing EXIT at any DOS prompt.  If run with the
  16. ; /R option, the progam is made resident and cannot be removed (but uses
  17. ; less memory).  Uses about 5600 bytes of memory with /R, over 8000 without.
  18. ; Requires CONVERT1.INC, CONVERT2.INC, VIDEO1.INC, and VIDEO2.INC on the
  19. ; default drive/path for assembly.
  20. ;
  21. ; The hot key is ALT-7.  Traps interrupt 16H and uses only BIOS routines for
  22. ; display, thus should work on most computers with most software.
  23. ;
  24. ; Show87 assumes that an 8087 is installed.  If one isn't installed, this
  25. ; program will probably hang the computer.
  26. ;
  27. ;----------------------------------------------------------------------------
  28. ;8 Ins Ptr  XXXXX | Prec      XX | ST(0) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX S
  29. ;0 Opr Ptr  XXXXX | Round  XXXXX | ST(1) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX H
  30. ;8 Op Code   XXXX | Infin  XXXXX | ST(2) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX O
  31. ;7 Control   XXXX |------------- | ST(3) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX W
  32. ;| Status    XXXX | Cond    XXXX | ST(4)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX 8
  33. ;S Tag       XXXX | Comp       X | ST(5)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX 7
  34. ;T ---------------| Test       X | ST(6)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX |
  35. ;A Stack Top    X | Exam  XXXXXX | ST(7)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX X
  36. ;T ------------------------------------------------------------------------ X
  37. ;E Except PX UX OX ZX DX IX    Intr Mask PX UX OX ZX DX IX    Ints XXXXXXXX X
  38. ;----------------------------------------------------------------------------
  39. ;
  40. ; Compare: > < = ?
  41. ; Test: + - 0 ?
  42. ; Examine: +Unorm +NAN -Unorm -NAN +Norm +Infin -Norm -Infin +0 -0 +Dnorm
  43. ;   -Dnorm Empty
  44. ; Precision: 24 53 64 ??
  45. ; Rounding: Near Up Down Trunc
  46. ; Infinity: Proj Affin
  47. ; Interrupts: Enabled Disabled
  48.  
  49. Ver_Hi Equ 1            ;ones version number
  50. Ver_Lo Equ 11           ;tens version number
  51.  
  52. Hotkey Equ 7e00h        ;hot key, Alt-7
  53.  
  54. StartRow Equ 0          ;screen row offset
  55. StartCol Equ 0          ;screen column offset
  56. Rows Equ 12             ;rows in display
  57. Cols Equ 76             ;columns in display
  58.  
  59. Atr_Bor Equ 07h         ;border attribute
  60. Atr_Mes Equ 70h         ;edge text attribute
  61. Atr_Lin Equ 07h         ;line attribute
  62. Atr_Tex Equ 07h         ;center text attribute
  63. Atr_Set Equ 07h         ;number and settings attribute
  64.  
  65. Sig_Bits Equ 57         ;number of significant bits in real number display
  66.  
  67. ;================================================
  68. ; Main program, execute shell after resetting
  69. ; interrupt 16H.
  70.  
  71.  Jmp Init       ;go to initialization
  72.  
  73. ;--- switch stack and set memory allocation
  74.  
  75. Start
  76.  Mov Bx, Offset Program_Stack   ;new stack top
  77.  Mov Sp, Bx                     ;switch to stack
  78.  Mov Cl, 4
  79.  Shr Bx, Cl             ;make paragraph
  80.  Inc Bx                 ;account for extra
  81.  
  82.  Test Status, Status1   ;check if resident mode
  83.  Jnz Main1
  84.  
  85.  Mov Ah, 4ah            ;function
  86.  Int 21h                ;execute
  87.  
  88. ;--- save the interrupt data
  89.  
  90. Main1
  91.  Push Bx
  92.  Push Es
  93.  Mov Ax, 3516h          ;function and interrupt number
  94.  Int 21h
  95.  Mov Word Original16, Bx        ;save offset
  96.  Mov Word Original16+2, Es      ;save segment
  97.  Pop Es
  98.  Pop Bx
  99.  
  100. ;--- load the new interrupt
  101.  
  102.  Mov Ax, 2516h                  ;function
  103.  Mov Dx, Offset Interrupt16     ;entry point offset
  104.  Int 21h                        ;execute
  105.  
  106.  Test Status, Status1   ;check if resident mode
  107.  Jnz Main3
  108.  
  109. ;--- initialize the EXEC parameter block and enter shell
  110.  
  111.  Push Es
  112.  Push Ds
  113.  Mov Prog_Off, Sp       ;save stack offset
  114.  Mov Prog_Seg, Ss       ;save stack segment
  115.  
  116.  Mov Ax, 4b00h
  117.  Mov Bx, Offset Parameter_Blk   ;pararmeter block location
  118.  Mov [Bx+4], Cs                 ;save the present segment
  119.  Mov Dx, CmdLoc                 ;program name offset
  120.  Mov Ds, [2ch]                  ;             segment
  121.  Int 21h
  122.  
  123.  Cli
  124.  Cs:
  125.  Mov Sp, Prog_Off       ;restore stack offset
  126.  Cs:
  127.  Mov Ss, Prog_Seg       ;restore stack segment
  128.  Sti
  129.  Pop Ds
  130.  Pop Es
  131.  
  132. ;--- show exit message
  133.  
  134.  Sub Al, Al
  135.  Mov Dx, Offset Closemes        ;normal termination message
  136.  Jnc Main2
  137.  Mov Al, 0ffh
  138.  Mov Dx, Offset Errormes        ;error message
  139. Main2
  140.  Mov Ah, 9                      ;function
  141.  Int 21h                        ;show message
  142.  
  143. ;--- finished
  144.  
  145.  Push Ax                ;save return code
  146.  Mov Ax, 2516h          ;function
  147.  Lds Dx, Original16     ;load original interrupt location
  148.  Int 21h                ;execute
  149.  Pop Ax
  150.  
  151.  Mov Ah, 4ch            ;exit function
  152.  Int 21h                ;execute
  153.  
  154. ;--- resident mode, terminate and stay resident
  155.  
  156. Main3
  157.  Mov Ax, 3100h  ;function and return code
  158.  Mov Dx, Bx     ;paragraphs to save
  159.  Int 21h        ;execute
  160.  
  161. ;================================================
  162. ; Control recieved through interrupt 16H.
  163.  
  164. Interrupt16 Proc Far
  165.  
  166. ;--- check if activation key
  167.  
  168.  Sti            ;interrrupts on
  169.  Cmp Ah, 0      ;check if key request
  170.  Je Inter1
  171.  Cmp Ah, 1      ;check if status request
  172.  Je Inter2
  173.  Cs:
  174.  Jmp Original16         ;non-key request, transfer directly to INT 16
  175.  
  176. ;--- key request, function 0
  177.  
  178. Inter1
  179.  Pushf                  ;flags on stack
  180.  Cs:
  181.  Call Original16        ;get key
  182.  Cmp Ax, HotKey         ;check if activation key
  183.  Je Inter5              ;jump if so
  184.  Iret
  185.  
  186. ;--- key status request
  187.  
  188. Inter2
  189.  Pushf                  ;flags on stack
  190.  Cs:
  191.  Call Original16        ;get key status
  192.  Jz Inter3              ;jump if no key
  193.  Pushf                  ;must save return flags
  194.  Cmp Ax, HotKey         ;check if activation key
  195.  Je Inter4              ;jump if so
  196.  Popf                   ;not key, restore flags
  197. Inter3
  198.  Ret 2
  199.  
  200. ;=== activation key detected, proceed with display
  201.  
  202. ;--- status only, must toss out key
  203.  
  204. Inter4
  205.  Add Sp, 2              ;throw out flags save by status
  206.  Sub Ah, Ah             ;get key function
  207.  Pushf                  ;flags on stack
  208.  Cs:
  209.  Call Original16        ;get key
  210.  Mov Ah, 1              ;reset actual function
  211.  
  212. ;--- save stack
  213.  
  214. Inter5
  215.  Cs:
  216.  Mov Stack_Seg, Ss      ;segment
  217.  Cs:
  218.  Mov Stack_Off, Sp      ;offset
  219.  
  220. ;--- switch to local stack
  221.  
  222.  Cli
  223.  Push Cs
  224.  Pop Ss                         ;set to local segment
  225.  Mov Sp, Offset Local_Stack     ;set to offset
  226.  Sti
  227.  
  228. ;--- save registers
  229.  
  230.  Pushf
  231.  Push Ax
  232.  Push Bx
  233.  Push Cx
  234.  Push Dx
  235.  Push Di
  236.  Push Si
  237.  Push Bp
  238.  Push Ds
  239.  Push Es
  240.  
  241. ;--- initialize
  242.  
  243.  Push Cs
  244.  Pop Ds         ;set data segment
  245.  Push Cs
  246.  Pop Es         ;set other data segment
  247.  
  248.  Cli
  249.  Fnsave State_Area      ;save the 8087 state
  250.  Fwait                  ;synchronize
  251.  Sti
  252.  
  253.  Cld                    ;normal direction
  254.  Mov IntFunc, Ah        ;save the function for termination
  255.  Call Video_Init        ;initialize display data
  256.  
  257.  Call Video_Cget        ;get the cursor location
  258.  Mov CurLoc, Dx         ;save it
  259.  
  260. ;--- save the screen area
  261.  
  262.  Mov Dh, StartRow               ;first row
  263.  Mov Di, Offset Save_Area       ;screen save area
  264.  
  265. Inter6
  266.  Mov Dl, StartCol       ;first column
  267.  
  268. Inter7
  269.  Call Video_Cset        ;move cursor
  270.  
  271.  Mov Ah, 8              ;function
  272.  Mov Bh, Video_Page     ;get the page
  273.  Push Di
  274.  Int 10h                ;execute, get character
  275.  Pop Di
  276.  Stosw                  ;store AH and AL
  277.  Inc Dl                 ;next column
  278.  
  279.  Cmp Dl, StartCol+Cols  ;check if past end
  280.  Jb Inter7              ;loop back if not
  281.  Inc Dh                 ;next row
  282.  
  283.  Cmp Dh, StartRow+Rows  ;check if past end
  284.  Jb Inter6              ;loop back if not
  285.  
  286. ;--- show main display
  287.  
  288.  Mov Bl, Atr_Set                                ;attribute
  289.  Mov Cx, StartRow*256+StartCol                  ;upper left corner
  290.  Mov Dx, (StartRow+Rows-1*256)+StartCol+Cols-1  ;lower right corner
  291.  Call Video_Cpag                                ;clear screen area
  292.  Mov Si, Offset Display1                ;main display string
  293.  Call Video_Wstr                        ;write to screen
  294.  
  295. ;--- show stats
  296.  
  297.  Call Display_State     ;show state
  298.  
  299. ;--- wait for key
  300.  
  301.  Mov Dx, (StartRow+Rows-1*256)+StartCol+Cols-1  ;lower right corner
  302.  Call Video_Cset                                ;move cursor there
  303.  
  304.  Sub Ah, Ah             ;function number
  305.  Pushf
  306.  Call Original16        ;get a key
  307.  
  308. ;--- restore the screen area
  309.  
  310.  Mov Dh, StartRow               ;first row
  311.  Mov Si, Offset Save_Area       ;screen save area
  312.  
  313. Inter8
  314.  Mov Dl, StartCol       ;first column
  315.  
  316. Inter9
  317.  Call Video_Cset        ;move cursor
  318.  
  319.  Lodsw                  ;load character and attribute
  320.  Mov Bl, Ah             ;attribute
  321.  Mov Ah, 9              ;function
  322.  Mov Bh, Video_Page     ;get the page
  323.  Mov Cx, 1              ;count
  324.  Push Si
  325.  Int 10h                ;execute, get character
  326.  Pop Si
  327.  
  328.  Inc Dl
  329.  Cmp Dl, StartCol+Cols  ;check if past end
  330.  Jb Inter9              ;loop back if not
  331.  Inc Dh                 ;next row
  332.  
  333.  Cmp Dh, StartRow+Rows  ;check if past end
  334.  Jb Inter8              ;loop back if not
  335.  
  336. ;--- finished
  337.  
  338.  Mov Dx, CurLoc         ;get cursor location
  339.  Call Video_Cset        ;set it
  340.  
  341.  Frstor State_Area      ;restore state
  342.  
  343.  Pop Es
  344.  Pop Ds
  345.  Pop Bp
  346.  Pop Si
  347.  Pop Di
  348.  Pop Dx
  349.  Pop Cx
  350.  Pop Bx
  351.  Pop Ax
  352.  Popf
  353.  
  354. ;--- restore original stack
  355.  
  356.  Cli
  357.  Cs:
  358.  Mov Ss, Stack_Seg      ;segment
  359.  Cs:
  360.  Mov Sp, Stack_Off      ;offset
  361.  Sti
  362.  
  363. ;--- transfer to interrupt 16H as if nothing had happened
  364.  
  365.  Cs:
  366.  Mov Ah, IntFunc        ;save the function for termination
  367.  Cs:
  368.  Jmp Original16         ;transfer to INT 16
  369.  Endp                   ;Interrupt16
  370.  
  371. ;================================================
  372. ; Display the 8087 state.
  373.  
  374. Display_State Proc Near
  375.  
  376. ;--- instruction pointer
  377.  
  378.  Mov Ax, State_Area+6   ;instruction pointer, lower 16 bits
  379.  Mov Bx, State_Area+8   ;                     upper 4 bits
  380.  Mov Cl, 12
  381.  Shr Bx, Cl             ;put the bits in the bottom
  382.  Mov Cx, 5*256+16       ;display width and base
  383.  Mov Dx, 1*256+11       ;display location offset
  384.  Call Display_Number    ;display
  385.  
  386. ;--- operand pointer
  387.  
  388.  Mov Ax, State_Area+10  ;operand pointer, lower 16 bits
  389.  Mov Bx, State_Area+12  ;                 upper 4 bits
  390.  Push Cx
  391.  Mov Cl, 12
  392.  Shr Bx, Cl             ;put the bits in the bottom
  393.  Pop Cx
  394.  Inc Dh                 ;next row
  395.  Call Display_Number    ;display
  396.  
  397. ;--- op code
  398.  
  399.  Mov Ax, State_Area+8           ;get the op code
  400.  And Ax, 0000011111111111b      ;mask out bits
  401.  Or Ax, 1101100000000000b       ;set implicit bits
  402.  Sub Bx, Bx                     ;clear high word
  403.  Mov Ch, 4                      ;new display width
  404.  Inc Dh                         ;next row
  405.  Inc Dl                         ;next column
  406.  Call Display_Number            ;display
  407.  
  408. ;--- control word
  409.  
  410.  Mov Ax, State_Area     ;control word
  411.  Inc Dh                 ;next row
  412.  Call Display_Number    ;display
  413.  
  414. ;--- status word
  415.  
  416.  Mov Ax, State_Area+2   ;status word
  417.  Inc Dh                 ;next row
  418.  Call Display_Number    ;display
  419.  
  420. ;--- tag word
  421.  
  422.  Mov Ax, State_Area+4   ;tag word
  423.  Inc Dh                 ;next row
  424.  Call Display_Number    ;display
  425.  
  426. ;--- stack top
  427.  
  428.  Call Get_Stack         ;get the stack top
  429.  Sub Ah, Ah
  430.  Add Dx, 0203h          ;add two to the rows and add three to the columns
  431.  Mov Cx, 1*256+10       ;display width and base
  432.  Call Display_Number    ;display
  433.  
  434. ;--- precision
  435.  
  436.  Mov Bl, State_Area+1   ;high word of control
  437.  And Bl, 11b            ;mask bits
  438.  Sub Bh, Bh
  439.  Mov Cl, 2              ;width
  440.  Mov Dx, 1*256+29               ;display location offset
  441.  Mov Di, Offset Dissta3b        ;table
  442.  Call Display_Istr              ;display string
  443.  
  444. ;--- rounding
  445.  
  446.  Mov Bl, State_Area+1   ;high word of control
  447.  And Bl, 1100b          ;mask bits
  448.  Sub Bh, Bh
  449.  Shr Bx
  450.  Shr Bx
  451.  Mov Cl, 5              ;width
  452.  Inc Dh
  453.  Sub Dl, 3                      ;display location offset
  454.  Mov Di, Offset Dissta4b        ;table
  455.  Call Display_Istr              ;display string
  456.  
  457. ;--- infinity
  458.  
  459.  Mov Bl, State_Area+1   ;high word of control
  460.  And Bl, 10000b         ;mask bit
  461.  Sub Bh, Bh
  462.  Mov Cl, 4
  463.  Shr Bx, Cl
  464.  Mov Cl, 5                      ;width
  465.  Inc Dh                         ;next row
  466.  Mov Di, Offset Dissta5b        ;table
  467.  Call Display_Istr              ;display string
  468.  
  469. ;--- condition codes
  470.  
  471.  Mov Al, State_Area+3   ;high byte of status
  472.  Call Adjst_Codes       ;adjust the condition codes
  473.  Sub Bx, Bx             ;clear high word
  474.  Mov Cx, 4*256+2        ;display width and base
  475.  Add Dx, 0201h          ;new location
  476.  Call Display_Number    ;display
  477.  
  478. ;--- comparison and test
  479.  
  480.  Call Get_Comp                  ;get the index
  481.  Mov Cl, 1                      ;width
  482.  Add Dx, 0103h                  ;location
  483.  Mov Di, Offset Dissta1b        ;table
  484.  Call Display_Istr              ;display string
  485.  
  486.  Inc Dh
  487.  Mov Di, Offset Dissta2b        ;table
  488.  Call Display_Istr              ;display string
  489.  
  490. ;--- examine
  491.  
  492.  Mov Al, State_Area+3   ;high byte of status
  493.  Inc Dh
  494.  Sub Dl, 5              ;location
  495.  Call Display_Exam      ;display
  496.  
  497. ;--- exception bit settings
  498.  
  499.  Mov Al, State_Area+2   ;get the bits
  500.  Mov Dx, 10*256+10      ;display offset
  501.  Call Display_Bits      ;display
  502.  
  503. ;--- mask bit settings
  504.  
  505.  Mov Al, State_Area     ;get the bits
  506.  Mov Dx, 10*256+41      ;display offset
  507.  Call Display_Bits      ;display
  508.  
  509. ;--- interrupts
  510.  
  511.  Mov Ax, State_Area     ;control word
  512.  Shl Ax                 ;shift bit to high byte
  513.  And Ah, 1b             ;mask
  514.  Mov Bl, Ah
  515.  Sub Bh, Bh
  516.  Mov Cl, -8             ;width
  517.  Mov Dx, 10*256+66      ;display offset
  518.  Mov Di, Offset Dissta6b        ;table
  519.  Call Display_Istr              ;display string
  520.  
  521. ;--- show stack data
  522.  
  523.  Call Display_Stack     ;show stack values
  524.  Ret
  525.  
  526. ;--- data
  527.  
  528. Dissta1a Db '>',0, '<',0, '=',0, '?',0
  529. Dissta1b Dw Offset Dissta1a, Offset Dissta1a+2,
  530.          Dw Offset Dissta1a+4, Offset Dissta1a+6
  531.  
  532. Dissta2a Db '+',0, '-',0, '0',0, '?',0
  533. Dissta2b Dw Offset Dissta2a, Offset Dissta2a+2,
  534.          Dw Offset Dissta2a+4, Offset Dissta2a+6
  535.  
  536. Dissta3a Db '24',0, '??',0, '53',0, '64',0
  537. Dissta3b Dw Offset Dissta3a, Offset Dissta3a+3,
  538.          Dw Offset Dissta3a+6, Offset Dissta3a+9
  539.  
  540. Dissta4a Db 'Near',0, 'Up',0, 'Down',0, 'Trunc',0
  541. Dissta4b Dw Offset Dissta4a, Offset Dissta4a+5,
  542.          Dw Offset Dissta4a+8, Offset Dissta4a+13
  543.  
  544. Dissta5a Db 'Proj',0, 'Affin',0
  545. Dissta5b Dw Offset Dissta5a, Offset Dissta5a+5
  546.  
  547. Dissta6a Db 'Enabled',0, 'Disabled',0
  548. Dissta6b Dw Offset Dissta6a, Offset Dissta6a+8
  549.  Endp           ;Display_State
  550.  
  551. ;================================================
  552. ; Display of the settings of six consecutive
  553. ; bits.
  554. ;
  555. ; In: AL= bit pattern; DX= row and column display
  556. ; offset.
  557.  
  558. Display_Bits Proc Near
  559.  Mov Ah, Al
  560.  Mov Bh, 20h                    ;first bit to check
  561.  Mov Cx, 6                      ;bits to check
  562.  Add Dx, StartRow*256+StartCol  ;real screen location
  563.  
  564. ;--- loop for each bit
  565.  
  566. Disbit1
  567.  Mov Al, '-'    ;not set sign
  568.  Test Ah, Bh    ;check if set
  569.  Jz Disbit2
  570.  Mov Al, '+'    ;set sign
  571.  
  572. Disbit2
  573.  Call Display_Char      ;display character
  574.  Shr Bh                 ;shift bit to test
  575.  Add Dl, 2              ;next location
  576.  Loop Disbit1
  577.  
  578.  Ret
  579.  Endp           ;Display_Bits
  580.  
  581. ;================================================
  582. ; Display the stack values.
  583.  
  584. Display_Stack Proc Near
  585.  Std
  586.  Mov Bx, Offset State_Area      ;save area
  587.  Add Bx, 14                     ;skip to numbers
  588.  Mov Cx, 8                      ;8087 stack entries
  589.  Mov Dh, StartRow+1             ;first display row
  590.  
  591. ;=== display a number
  592.  
  593. Disstk1
  594.  Push Bx
  595.  Push Cx
  596.  
  597.  Fld Tbyte [Bx]         ;load number
  598.  
  599. ;--- get number type or set to empty
  600.  
  601.  Push Cx                ;save stack number
  602.  Call Get_Stack         ;get the stack top
  603.  Mov Cl, Al
  604.  Mov Ax, State_Area+4   ;get the tag word
  605.  Shl Cl                 ;two bits for each tag
  606.  Ror Ax, Cl             ;adjust so first tag is in low bits
  607.  Pop Cx
  608.  Mov Ch, 8
  609.  Sub Ch, Cl
  610.  Shl Ch                 ;bits to shift to put set tag low
  611.  Mov Cl, Ch
  612.  Shr Ax, Cl             ;tag bits to lower bit locations 0 and 1
  613.  And Ax, 11b            ;mask bits
  614.  
  615. ;--- check type
  616.  
  617.  Cmp Ax, 11b            ;check if empty
  618.  Je Disstk2
  619.  
  620.  Fxam                   ;check number type
  621.  Fstsw Status87         ;store status
  622.  
  623.  Cmp Ax, 10b            ;check if special
  624.  Je Disstk3             ;jump if so
  625.  
  626. ;--- normal value
  627.  
  628.  Call Display_Float     ;display decimal number
  629.  Jmps Disstk4
  630.  
  631. ;--- empty
  632.  
  633. Disstk2
  634.  Mov Status87, 0ffffh   ;set all bits
  635.  
  636. ;--- special number
  637.  
  638. Disstk3
  639.  Call Display_Hex       ;display hexadecimal bit pattern
  640.  
  641. ;--- finished with a single stack number
  642.  
  643. Disstk4
  644.  Mov Al, Byte Status87+1        ;high byte of status
  645.  Call Display_Exam              ;display
  646.  Pop Cx
  647.  Pop Bx
  648.  
  649.  Add Bx, 10             ;next stack entry
  650.  Inc Dh                 ;next row
  651.  Loop Disstk1           ;loop for each entry
  652.  
  653.  Cld
  654.  Ret
  655.  Endp           ;Display_Stack
  656.  
  657. ;================================================
  658. ; Display a decimal floating point number.
  659. ;
  660. ; In: ST(0)= number; DH= row.
  661. ;
  662. ; Out: DX= row and column one space after number.
  663.  
  664. Display_Float Proc Near
  665.  
  666. ;--- convert number and store
  667.  
  668.  Mov Ax, Sig_Bits               ;number of significant bits
  669.  Call Flt2dec                   ;convert to decimal
  670.  Mov Si, Offset Number_Store    ;storage for number
  671.  Fbstp Tbyte [Si]               ;save number string
  672.  Fwait
  673.  
  674. ;--- display the mantissa sign
  675.  
  676.  Push Ax                ;save the exponent
  677.  Mov Dl, StartCol+40    ;column
  678.  
  679.  Add Si, 9              ;goto last byte
  680.  Lodsb                  ;get the sign byte
  681.  Mov Ah, '+'
  682.  Test Al, 80h           ;check if negative
  683.  Jz Disflt1
  684.  Mov Ah, '-'
  685. Disflt1
  686.  Mov Al, Ah             ;sign
  687.  Call Display_Char      ;display character
  688.  
  689. ;--- first two digits and decimal point
  690.  
  691.  Lodsb
  692.  Call Display_Bhi       ;high digit
  693.  Push Ax
  694.  Mov Al, '.'            ;decimal point
  695.  Call Display_Char      ;write point
  696.  Pop Ax
  697.  Call Display_Blo       ;low digit
  698.  
  699. ;--- remaining mantissa digits
  700.  
  701.  Mov Cx, 8              ;remaining number of packed bytes
  702.  
  703. Disflt2
  704.  Lodsb
  705.  Call Display_Bhi       ;high digit
  706.  Call Display_Blo       ;low digit
  707.  Loop Disflt2
  708.  
  709. ;--- exponent sign
  710.  
  711.  Pop Ax
  712.  Inc Dl                 ;skip to exponent location
  713.  
  714.  Mov Cl, '+'            ;plus
  715.  Add Ax, 17             ;adjust for decimal point
  716.  Jns Disflt3            ;jump if not minus
  717.  Mov Cl, '-'            ;minus
  718.  Neg Ax
  719. Disflt3
  720.  Push Ax
  721.  Mov Al, Cl
  722.  Call Display_Char      ;display
  723.  Pop Ax
  724.  
  725. ;--- exponent
  726.  
  727.  Sub Bx, Bx             ;clear high word
  728.  Mov Cx, 5*256+10       ;load width and base
  729.  Call Display_Number    ;display
  730.  Add Dl, 6              ;position cursor at end
  731.  Ret
  732.  
  733. ;------------------------------------------------
  734. ; Display a high packed BCD digit.
  735. ;
  736. ; In: AL= packed BCD digits; BL= attribute.
  737.  
  738. Display_Bhi Proc Near
  739.  Push Ax
  740.  Shr Al
  741.  Shr Al
  742.  Shr Al
  743.  Shr Al                 ;shift the high bits
  744.  Add Al, '0'            ;convert to decimal digit
  745.  Call Display_Char      ;write point
  746.  Pop Ax
  747.  Ret
  748.  Endp           ;Display_Bhi
  749.  
  750. ;------------------------------------------------
  751. ; Display a low packed BCD digit.
  752. ;
  753. ; In: AL= packed BCD digits; BL= attribute.
  754.  
  755. Display_Blo Proc Near
  756.  Push Ax
  757.  And Al, 0fh            ;mask relevant bits
  758.  Add Al, '0'            ;convert to decimal digit
  759.  Call Display_Char      ;write point
  760.  Pop Ax
  761.  Ret
  762.  Endp                   ;Display_Blo
  763.  
  764.  Endp                   ;Display_Float
  765.  
  766. ;================================================
  767. ; Display the bit pattern of a floating point
  768. ; number.
  769. ;
  770. ; In: ST(0)= number; DH= row.
  771. ;
  772. ; Out: DX= row and column one space after number.
  773.  
  774. Display_Hex Proc Near
  775.  Fstp Dishex1           ;store number
  776.  Fwait                  ;wait just in case
  777.  
  778.  Mov Al, '='            ;starting character
  779.  Mov Dl, StartCol+43    ;column
  780.  Call Display_Char      ;display
  781.  
  782.  Mov Cx, 8              ;bytes
  783.  Lea Si, Dishex1+7      ;last byte of mantissa
  784.  Call Display_Byts      ;display
  785.  
  786.  Mov Al, '='            ;starting character
  787.  Add Dl, 2              ;column
  788.  Call Display_Char      ;display
  789.  
  790.  Mov Cx, 2              ;bytes
  791.  Lea Si, Dishex1+9      ;last byte of exponent
  792.  Call Display_Byts      ;display
  793.  
  794.  Inc Dl                 ;next column
  795.  Ret
  796.  
  797. ;--- storage for the tempory real number
  798.  
  799. Dishex1 Label Tbyte
  800.  Ds 10
  801.  
  802. ;------------------------------------------------
  803. ; Display backwards bytes.
  804. ;
  805. ; In: SI= starting location; CX= bytes.
  806.  
  807. Display_Byts Proc Near
  808.  Pushf
  809.  Std
  810.  Sub Ah, Ah             ;clear high byte
  811.  Sub Bx, Bx             ;clear high word
  812.  
  813. Disbys1
  814.  Lodsb                  ;load byte
  815.  Push Cx
  816.  Push Si
  817.  Mov Cx, 2*256+16       ;format
  818.  Call Display_Number    ;display
  819.  Add Dl, 2              ;next location
  820.  Pop Si
  821.  Pop Cx
  822.  Loop Disbys1           ;loop for each byte
  823.  Popf
  824.  Ret
  825.  Endp                   ;Display_Byts
  826.  
  827.  Endp                   ;Display_Hex
  828.  
  829. ;================================================
  830. ; Display an FXAM result.
  831. ;
  832. ; In: AL= high byte of 8087 status; DX= row and
  833. ; column location.
  834.  
  835. Display_Exam Proc Near
  836.  Call Adjst_Codes               ;adjust the condition codes
  837.  Mov Bx, Ax
  838.  Mov Cl, 6                      ;width
  839.  Mov Di, Offset Disexm1b        ;table
  840.  Call Display_Istr              ;display string
  841.  Ret
  842.  
  843. ;--- data
  844.  
  845. Disexm1a Db '+Unorm',0, '+NAN',0, '-Unorm',0, '-NAN',0,
  846.          Db '+Norm',0, '+Infin',0, '-Norm',0, '-Infin',0,
  847.          Db '+0',0, '-0',0, '+Dnorm',0, '-Dnorm',0, 'Empty',0
  848. Disexm1b Dw Offset Disexm1a, Offset Disexm1a+7,
  849.          Dw Offset Disexm1a+12, Offset Disexm1a+19
  850.          Dw Offset Disexm1a+24, Offset Disexm1a+30
  851.          Dw Offset Disexm1a+37, Offset Disexm1a+43
  852.          Dw Offset Disexm1a+50, Offset Disexm1a+70
  853.          Dw Offset Disexm1a+53, Offset Disexm1a+70
  854.          Dw Offset Disexm1a+56, Offset Disexm1a+70
  855.          Dw Offset Disexm1a+63, Offset Disexm1a+70
  856.  
  857.  Endp           ;Display_Exam
  858.  
  859. ;================================================
  860. ; Get the stack top number.
  861. ;
  862. ; Out: AL= stack number.
  863.  
  864. Get_Stack Proc Near
  865.  Mov Al, State_Area+3   ;get the high byte of the status word
  866.  And Al, 00111000b      ;mask out stack
  867.  Shr Al
  868.  Shr Al
  869.  Shr Al                 ;adjust
  870.  Ret
  871.  Endp           ;Get_Stack
  872.  
  873. ;================================================
  874. ; Adjust the condition codes to consecutive bits.
  875. ;
  876. ; In: AL= high byte of status.
  877. ; Out: AX= condition codes in consecutive, least
  878. ; significant bit locations.
  879.  
  880. Adjst_Codes Proc Near
  881.  Mov Ah, Al
  882.  And Al, 00000111b      ;mask C2 to C0 bits
  883.  And Ah, 01000000b      ;mask C3 bit
  884.  Shr Ah
  885.  Shr Ah
  886.  Shr Ah                 ;shift bit over
  887.  Or Al, Ah              ;combine
  888.  Sub Ah, Ah
  889.  Ret
  890.  Endp           ;Adjst_Codes
  891.  
  892. ;================================================
  893. ; Get an index for the comparison and test
  894. ; instructions. Based on the condition codes.
  895. ;
  896. ; Out: BX= index.
  897.  
  898. Get_Comp Proc Near
  899.  Sub Bx, Bx
  900.  Mov Al, State_Area+3   ;high byte of state
  901.  And Al, 01000101b      ;mask C3 C2 and C0
  902.  Cmp Al, 00000000b      ;check if 0 0 0
  903.  Je Getcom1
  904.  Inc Bx
  905.  Cmp Al, 00000001b      ;check if 0 0 1
  906.  Je Getcom1
  907.  Inc Bx
  908.  Cmp Al, 01000000b      ;check if 1 0 0
  909.  Je Getcom1
  910.  Inc Bx
  911.  
  912. Getcom1 Ret
  913.  Endp           ;Get_Comp
  914.  
  915. ;================================================
  916. ; Display a single character.
  917. ;
  918. ; In: AL= character; DX= location.
  919.  
  920. Display_Char Proc Near
  921.  Mov Bl, Atr_Set        ;attribute
  922.  Call Video_Cset        ;set cursor location
  923.  Call Video_Wchr        ;write character
  924.  Inc Dl                 ;next column
  925.  Ret
  926.  Endp                   ;Display_Char
  927.  
  928. ;================================================
  929. ; Display a zero padded number to a location.
  930. ;
  931. ; In: BX:AX= number; CL= number base; CH= the
  932. ; display width; DX= location.
  933.  
  934. Display_Number Proc Near
  935.  Push Ax
  936.  Push Cx
  937.  Push Dx
  938.  Add Dx, StartRow*256+StartCol  ;real screen location
  939.  Call Video_Cset                ;move cursor
  940.  
  941.  Push Cx
  942.  Sub Ch, Ch
  943.  Mov Dx, Bx                     ;high word
  944.  Mov Di, Offset Number_Store    ;place to store
  945.  Call Convert_Num               ;convert to string
  946.  Pop Cx
  947.  
  948.  Mov Al, '0'            ;pad character
  949.  Mov Cl, Ch
  950.  Sub Ch, Ch
  951.  Mov Si, Di
  952.  Call Video_Wstrr       ;display number
  953.  Pop Dx
  954.  Pop Cx
  955.  Pop Ax
  956.  Ret
  957.  Endp           ;Display_Number
  958.  
  959. ;================================================
  960. ; Given an index and a table, displays a space
  961. ; padded string to a location.
  962. ;
  963. ; In: BX= index; DI= table offset; CL= width, if
  964. ; negative, the string is right justified instead
  965. ; of left; DX= location.
  966.  
  967. Display_Istr Proc Near
  968.  Push Ax
  969.  Push Bx
  970.  Push Cx
  971.  Push Dx
  972.  Push Si
  973.  
  974. ;--- locate cursor
  975.  
  976.  Add Dx, StartRow*256+StartCol  ;real screen location
  977.  Call Video_Cset                ;move cursor
  978.  
  979. ;--- display string
  980.  
  981.  Mov Al, ' '            ;pad with spaces
  982.  Shl Bx                 ;two bytes for offset
  983.  Sub Ch, Ch
  984.  Mov Si, [Di+Bx]        ;get the string location
  985.  
  986.  Cmp Cl, 0
  987.  Jg Disist1
  988.  
  989.  Neg Cl                 ;absolute value
  990.  Call Video_Wstrl       ;display, left justified
  991.  Jmps Disist2
  992.  
  993. Disist1
  994.  Call Video_Wstrr       ;display, right justified
  995.  
  996. Disist2
  997.  Pop Si
  998.  Pop Dx
  999.  Pop Cx
  1000.  Pop Bx
  1001.  Pop Ax
  1002.  Ret
  1003.  Endp           ;Display_Istr
  1004.  
  1005. ;================================================
  1006. ; External files.
  1007.  
  1008.  Include 'Video1.Inc'
  1009.  Include 'Video2.Inc'
  1010.  Include 'Convert1.Inc'
  1011.  Include 'Convert2.Inc'
  1012.  
  1013. ;================================================
  1014. ; Data.
  1015.  
  1016. ;--- program status
  1017.  
  1018. Status1 Equ 01h         ;execute in memory resident mode
  1019.  
  1020. Status Db 0
  1021.  
  1022. ;--- original interrupt 16H
  1023.  
  1024. Original16 Label Dword
  1025.  Dw ?                   ;offset
  1026.  Dw ?                   ;segment
  1027.  
  1028. ;--- shell parameter block
  1029.  
  1030. Parameter_Blk Label Word
  1031.  Dw 0                           ;use default environment
  1032.  Dw Offset CmdTail              ;command tail
  1033.  Dw ?                           ;present segment
  1034.  Dw -1                  ;
  1035.  Dw -1                  ;
  1036.  Dw -1                  ;-- no FCB'S
  1037.  Dw -1                  ;
  1038.  
  1039. CmdTail Db 0, 13
  1040.  
  1041. ;--- saved stack addresses
  1042.  
  1043. Prog_Off Dw ?           ;-- save area through EXEC function
  1044. Prog_Seg Dw ?           ;
  1045.  
  1046. Stack_Off Dw ?          ;-- save area for alternate int 16
  1047. Stack_Seg Dw ?          ;
  1048.  
  1049. ;--- other data
  1050.  
  1051. CmdLoc Dw ?             ;offset of command processor in environment
  1052. Intfunc Db ?            ;int 16 request
  1053. CurLoc Dw ?             ;saved cursor location
  1054.  
  1055. ;--- main display string
  1056.                                               
  1057. Display1 Label Byte
  1058.  Db FrmAtr, Atr_Bor
  1059.  Db FrmLoc, StartRow, StartCol, 219, FrmHor, 223, Cols-2, 219
  1060.  Db FrmLoc, StartRow+1, StartCol, FrmVer, 219, Rows-2
  1061.  Db FrmLoc, StartRow+1, StartCol+Cols-1, FrmVer, 219, Rows-2
  1062.  Db FrmLoc, StartRow+Rows-1, StartCol, 219, FrmHor, 220, Cols-2, 219
  1063.  
  1064.  Db FrmAtr, Atr_Lin
  1065.  Db FrmLoc, StartRow+9, StartCol+2, FrmHor, 196, 72
  1066.  Db FrmLoc, StartRow+1, StartCol+32, FrmVer, 179, 8, 193
  1067. ;this prints some other lines, but I decided it looked better without them
  1068. ; Db FrmLoc, StartRow+1, StartCol+17, FrmVer, 179, 8
  1069. ; Db FrmLoc, StartRow+7, StartCol+2, FrmHor, 196, 15, 180
  1070. ; Db FrmLoc, StartRow+4, StartCol+17, 195, FrmHor, 196, 13
  1071.  
  1072.  Db FrmAtr, Atr_Mes
  1073.  Db FrmLoc, StartRow+1, StartCol, '8'
  1074.  Db FrmLoc, StartRow+2, StartCol, '0'
  1075.  Db FrmLoc, StartRow+3, StartCol, '8'
  1076.  Db FrmLoc, StartRow+4, StartCol, '7'
  1077.  Db FrmLoc, StartRow+6, StartCol, 'S'
  1078.  Db FrmLoc, StartRow+7, StartCol, 'T'
  1079.  Db FrmLoc, StartRow+8, StartCol, 'A'
  1080.  Db FrmLoc, StartRow+9, StartCol, 'T'
  1081.  Db FrmLoc, StartRow+10, StartCol, 'E'
  1082.  
  1083.  Db FrmLoc, StartRow+1, StartCol+Cols-1, 'S'
  1084.  Db FrmLoc, StartRow+2, StartCol+Cols-1, 'H'
  1085.  Db FrmLoc, StartRow+3, StartCol+Cols-1, 'O'
  1086.  Db FrmLoc, StartRow+4, StartCol+Cols-1, 'W'
  1087.  Db FrmLoc, StartRow+5, StartCol+Cols-1, '8'
  1088.  Db FrmLoc, StartRow+6, StartCol+Cols-1, '7'
  1089.  Db FrmLoc, StartRow+8, StartCol+Cols-1, Ver_Hi\10+'0'
  1090.  Db FrmLoc, StartRow+9, StartCol+Cols-1, Ver_Lo/10+'0'
  1091.  Db FrmLoc, StartRow+10, StartCol+Cols-1, Ver_Lo\10+'0'
  1092.  
  1093.  Db FrmAtr, Atr_Tex
  1094.  Db FrmLoc, StartRow+1, StartCol+2, 'Ins Ptr'
  1095.  Db FrmLoc, StartRow+2, StartCol+2, 'Opr Ptr'
  1096.  Db FrmLoc, StartRow+3, StartCol+2, 'Op Code'
  1097.  Db FrmLoc, StartRow+4, StartCol+2, 'Control'
  1098.  Db FrmLoc, StartRow+5, StartCol+2, 'Status'
  1099.  Db FrmLoc, StartRow+6, StartCol+2, 'Tag'
  1100.  
  1101.  Db FrmLoc, StartRow+8, StartCol+2, 'Stack Top'
  1102.  
  1103.  Db FrmLoc, StartRow+1, StartCol+19, 'Prec'
  1104.  Db FrmLoc, StartRow+2, StartCol+19, 'Round'
  1105.  Db FrmLoc, StartRow+3, StartCol+19, 'Infin'
  1106.  
  1107.  Db FrmLoc, StartRow+5, StartCol+19, 'Cond'
  1108.  Db FrmLoc, StartRow+6, StartCol+19, 'Comp'
  1109.  Db FrmLoc, StartRow+7, StartCol+19, 'Test'
  1110.  Db FrmLoc, StartRow+8, StartCol+19, 'Exam'
  1111.  
  1112.  Db FrmLoc, StartRow+1, StartCol+34, 'ST(0)'
  1113.  Db FrmLoc, StartRow+2, StartCol+34, 'ST(1)'
  1114.  Db FrmLoc, StartRow+3, StartCol+34, 'ST(2)'
  1115.  Db FrmLoc, StartRow+4, StartCol+34, 'ST(3)'
  1116.  Db FrmLoc, StartRow+5, StartCol+34, 'ST(4)'
  1117.  Db FrmLoc, StartRow+6, StartCol+34, 'ST(5)'
  1118.  Db FrmLoc, StartRow+7, StartCol+34, 'ST(6)'
  1119.  Db FrmLoc, StartRow+8, StartCol+34, 'ST(7)'
  1120.  
  1121.  Db FrmLoc, StartRow+10, StartCol+2, 'Except'
  1122.  Db FrmLoc, StartRow+10, StartCol+9, FrmStr, Offset Display2
  1123.  Db FrmLoc, StartRow+10, StartCol+30, 'Intr Mask'
  1124.  Db FrmLoc, StartRow+10, StartCol+40, FrmStr, Offset Display2
  1125.  Db FrmLoc, StartRow+10, StartCol+61, 'Ints'
  1126.  
  1127.  
  1128.  Db FrmAtr, Atr_Set
  1129.  Db 0
  1130.  
  1131. Display2 Db 'P  U  O  Z  D  I', 0
  1132.  
  1133. ;--- exit message
  1134.  
  1135. Closemes Db 13,10,'SHOW87 is removed from memory.',13,10,'$'
  1136. Errormes Db 13,10,'Error: Could not install SHOW87', 13,10,'$'
  1137.  
  1138. ;================================================
  1139. ; Uninitialized data.
  1140.  
  1141. Save_Area Label Byte            ;screen data
  1142.  Org +(Rows * Cols * 2)
  1143. State_Area Label Anysize        ;area to save the 8087 state
  1144.  Org +94
  1145. Status87 Label Word             ;8087 status storage for checking numbers
  1146.  Org +2
  1147. Number_Store Label Byte         ;storage for decimal number strings
  1148.  Org +11
  1149.  Org +100h
  1150. Local_Stack Label Byte          ;local stack for state display
  1151.  Org +100h
  1152. Program_Stack Label Byte        ;main program stack
  1153.  
  1154.  Org Offset Save_Area   ;fix location
  1155.  
  1156. ;================================================
  1157. ; Transient code.  Exists in unitialized data 
  1158. ; area, must be executed before the data area is
  1159. ; used.
  1160.  
  1161. ;--- display opening message
  1162.  
  1163. Init
  1164.  Mov Dx, Offset Openmes         ;message
  1165.  Mov Ah, 9                      ;function
  1166.  Int 21h                        ;display
  1167.  
  1168. ;--- find command processor
  1169.  
  1170.  Push Es
  1171.  Mov Cx, 8              ;string length
  1172.  Sub Di, Di             ;starting offset of environment
  1173.  Mov Es, [2ch]          ;environment segment
  1174.  
  1175. ;--- loop for each string in the environment
  1176.  
  1177. Init1
  1178.  Es:
  1179.  Cmp Byte [Di], 0       ;check if end of environment
  1180.  Je Init8
  1181.  
  1182.  Mov Cx, 8              ;string length
  1183.  Mov Si, Offset Comspec ;string location
  1184.  
  1185.  Repe
  1186.  Cmpsb          ;compare bytes
  1187.  Je Init3       ;jump if found
  1188.  
  1189. Init2
  1190.  Es:
  1191.  Cmp Byte [Di-1], 0     ;see if stopped on end of string
  1192.  Je Init1
  1193.  Inc Di                 ;next byte
  1194.  Jmps Init2
  1195.  
  1196. Init3
  1197.  Mov CmdLoc, Di        ;save location
  1198.  Pop Es
  1199.  
  1200. ;--- set resident flag
  1201.  
  1202.  Mov Si, 80h            ;command tail
  1203.  Lodsb                  ;get the length
  1204.  Or Al, Al              ;check if none
  1205.  Jz Init6
  1206.  Mov Cl, Al
  1207.  Sub Ch, Ch             ;put count in CX
  1208.  
  1209. ;--- loop through characters in command tail
  1210.  
  1211. Init4
  1212.  Lodsb                  ;load next byte
  1213.  Cmp Al, '/'            ;check if switch
  1214.  Je Init7               ;jump if so
  1215. Init5
  1216.  Loop Init4             ;otherwise loop back
  1217.  
  1218. Init6
  1219.  Jmp Start
  1220.  
  1221. ;--- found slash
  1222.  
  1223. Init7
  1224.  Dec Cx                 ;reduce count
  1225.  Jz Init6               ;jump if no more bytes
  1226.  
  1227.  Lodsb                  ;load command character
  1228.  Sub Al, 'a'-'A'        ;convert to upper-case
  1229.  Cmp Al, 'R'            ;check if R
  1230.  Jne Init5              ;if not, go back to loop
  1231.  Xor Status, Status1    ;set (or clear) flag
  1232.  Jmp Start
  1233.  
  1234. ;--- could not find COMSPEC=
  1235.  
  1236. Init8
  1237.  Mov Dx, Offset Errormes        ;error message
  1238.  Mov Ah, 9                      ;function
  1239.  Int 21h                        ;show message
  1240.  
  1241.  Mov Ax, 4cffh          ;exit function
  1242.  Int 21h                ;execute
  1243.  
  1244. ;--- transient data
  1245.  
  1246. Openmes Db 13,10
  1247.         Db 'SHOW87, Version '
  1248.         Db Ver_Hi\10+'0', '.', Ver_Lo/10+'0', Ver_Lo\10+'0', 13, 10
  1249.         Db 'Copyright (c) 1987-1988 Eric Tauck',13,10
  1250.         Db 'All rights reserved',13,10,'$'
  1251.  
  1252. ;--- command environment string
  1253.  
  1254. Comspec Db 'COMSPEC='
  1255.